# print("hello world")
# a=20.4567;
# print(round(a,1))
# print(round(a,2))
# print(round(a,3))
# print(round(a,4))
# print("\"Yes,\" they said.")
# s = 'First line.\nSecond line.'
# print('c\sser\neveo')
# print(r'c\sser\neveo')
# print("""/ pritn
#         -h home
#         -s school
#         """)
# print("py""thon")
# s="python"
# print(s[len(s)-1:0:-1])
# s=s[::-1]
# print(s)
#s1=input()
# s2=input()
# a, c = map(int, s1.split(":"))
# b, d = map(int, s2.split(":"))
# if d>c :
#     print(b - a, d - c, sep=" ")
# else :
#     d+=60
#     b-=1
#     print(b-a,d-c,sep=" ")

import random


import random

# import math
#
# def lcm(a,b):
#     return abs(a*b)//math.gcd(a,b)
#
# try:
#     while True:
#         input_data = input().strip()
#         if not input_data:
#             break
#         l, r = map(int, input_data.split())
#         print(math.gcd(l,r),lcm(l,r),sep=" ")
# except EOFError:
#     pass
import math

# try:
#     while True:
#         a = input()
#         in_put = input()
#         try:
#             in_put=int(in_put)
#         except NameError:
#             print("the input is not numerical")
#             continue
#         try:
#             in_put=int(in_put)
#         except ZeroDivisionError:
#             print("zero division error")
#             continue
#         print("{:.2f}".format(a/in_put))
# except EOFError:
#     pass
# int_put = input()
# l, r = map(int, int_put.split(" "))
# count=0
# for num in range(l,r):
#     if (num*num)%(10**(len(str(num))))==num :
#         count+=1
#         print(num)
# if count==0:
#     print(None)

# import turtle
# import datetime
#
# l = turtle.Turtle()
# l.speed(6)
#
#
# screen = turtle.Screen()
# screen.setup(600, 600)
# screen.title("使用turtle绘制螺旋线")
#
# def draw():
#     size = 5
#     count=50
#     while count>=0:
#         l.forward(size)
#         l.right(90)
#         size += 5
#         count-=1
#
# draw()
#
# time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
#
#
# l.penup()
# l.goto(200, -270)
# l.pendown()
# l.write(f"学号: {202311071317}\n姓名: {"王凯"}\n时间: {time}", align="right", font=("Arial", 12, "normal"))
#
# turtle.done()


# import turtle
#
# # 设置画布
# screen = turtle.Screen()
# screen.bgcolor("white")
#
# # 创建海龟对象
# doraemon = turtle.Turtle()
# doraemon.pensize(3)
#
#
# def draw_circle(turtle, radius, color):
#     turtle.color(color)
#     turtle.begin_fill()
#     turtle.circle(radius)
#     turtle.end_fill()
#
#
# # 绘制脸部背景
# doraemon.penup()
# doraemon.goto(0, -100)
# doraemon.pendown()
# draw_circle(doraemon, 100, "blue")
#
# # 绘制眼睛
# for position in [(-40, 20), (40, 20)]:
#     doraemon.penup()
#     doraemon.goto(position)
#     doraemon.pendown()
#     draw_circle(doraemon, 15, "white")
#
#     # 眼珠
#     doraemon.penup()
#     doraemon.goto(position[0] + 6, position[1] + 3)
#     doraemon.pendown()
#     draw_circle(doraemon, 7, "black")
#
# # 绘制鼻子
# doraemon.penup()
# doraemon.goto(0, 40)
# doraemon.pendown()
# draw_circle(doraemon, 8, "red")
#
# # 简单的嘴巴
# doraemon.penup()
# doraemon.goto(-20, 0)
# doraemon.pendown()
# doraemon.right(90)
# doraemon.circle(20, 180)
#
# # 隐藏海龟图标并完成绘图
# doraemon.hideturtle()
# turtle.done()


#use={"han":'njy',"bhde":'ggg',"hjk":'gggg'}
# print(use)
# for user,status in use.copy().items():
#     if status=='ggg':
#         del use[user]
# print(use)
#
# a_use={}
# for use1,status in use.items():
#     if status!='ggg':
#         a_use[use1]=status
# print(use)
# print()

# for index,item in enumerate(list(range(1,6))):
#     print(f"index:{index},item:{item}")
# my_list = [5, 6, 7, 8, 9]
# new_list = [item for item in my_list]
# # print(new_list)
# print(item for item in my_list)
#for i in range(10):
#     if i==9:
#         print(i)
# else:
#     print(10)
# n=5
# while n:
#     print(n)
#     n-=1
# else:
#     print('while-else')
# print(1,2)
# def http(status):
#     match status:
#         case 'a':
#             print('a')
#         case "b":
#             print('b')
#         case _:
#             print(None)
#
# http('a')
# http('b')
# http('c')
# point=[(1,2),(2,3)]
# match point:
#     case (0,0):
#         print("(0,0)")
#     case _ :
#         print(None)
#
# print(reduce(operator.mul, map(int, input().strip().split()), 1))
# def isSymmetric(n):
#     n=str(n)
#     s=n[::-1]
#     if n==s:
#         return True
#     return False

# n=input()
# while True:
#        n+=1
#        if isSymmetric(n)==True:  #若n是回文数，则输出结果并结束循环
#             print(n)
#             break
# s=n[::-1]
# print(s)
# def judge(password):
#     level=0
#     if len(password)>=8:
#         level+=1
#     for item in password:
#         if 'a'<=item<='z':
#             level+=1
#         elif 'A'<=item<='Z':
#             level+=1
#         elif '0'<=item<='9':
#             level+=1
#     return level

# password=input()
# print("密码{}强度为{}".format(password,judge(password)))


# def isPerfectNum(num):
#     ret=[]
#     sum=0
#     for i in range(1,num-1):
#         if num%i==0:
#             ret.append(i)
#     for i in ret:
#         sum+=i
#     if sum==num:
#         return True
#
#     return False
#
# n=int(input())
#
# for i in range(2,n+1):
#     if isPerfectNum(i):
#        print(i)

import random


# def myshuffle(s):
#     ch=list(s)
#     n=len(ch)
#
#     ch1=[]
#     while n>0:
#         i=random.randint(0,n-1)
#         ch1.append(ch[i])
#         del ch[i]
#         n-=1
#
#     return ''.join(ch1)

# random.seed(0)
#
# s = input()
#
# print(myshuffle(s))

# def score(quiz,usual,end,quiz_rate=0.3,usual_rate=0.15):
#     if quiz_rate==0.3 and usual_rate==0.15:
#         n=quiz*quiz_rate+usual*usual_rate+end*(1-quiz_rate-usual_rate)
#         return n
#     else :
#         n = quiz * quiz_rate + usual * usual_rate + end * (1 - quiz_rate - usual_rate)
#         return n




# a, b, c, d, e = eval(input())
# print("按照默认比例，期末总评成绩={:.1f}".format(score(a, b, c)))
# print("按照输入的比例，期末总评成绩={:.1f}".format(score(a, b, c, d, e)))


#def my_decorator(func):
#     def wrapper(*args, **kwargs):
#         print("执行前操作")
#         res=func(*args, **kwargs)
#         print("执行后操作")
#         return res
#     return wrapper
# @my_decorator
# def say_hello(s):
#     print(s)
# s=input()
# say_hello(s)
import math





# def factors(num):
#     global facs
#     div=2
#     facs=[]
#     while num>1:
#         while num%div==0:
#             facs.append(div)
#             num//=div
#         div+=1
#     return facs
#
#
#
# facs=[]
# n=int(input())
# factors(n)
# result='*'.join(map(str,facs))
# if n==eval(result):
#     print(n,'='+result)

# class Book:
#     sName = None
#     sNo = None
#     fPrice = None
#     def __init__(self, sName, sNo,fPrice):
#         self.sName = sName
#         self.sNo = sNo
#         self.fPrice = fPrice
#         print("Book destroyed-"+self.sName,self.sNo,round(self.fPrice,2),sep=",")
#         # print(round(self.fPrice,2))
#     def __del__(self):
#         del self.sName
#         del self.sNo
#         del self.fPrice
#         self=None
#
# sName = input()  #输入书名
# sNo = input() #输入书号
# fPrice = float(input())   #输入单价
# b = Book(sName,sNo,fPrice)
# b = None   #触发b对象的__del__方法的执行

# class St:
#     lt=[]
#     def __init__(self,lt):
#         self.lt=list(lt)
#     def Max(self):
#         return max(self.lt)
#     def Min(self):
#         return min(self.lt)
#     def ls(self):
#         # print('[',end="")
#         # print(self.lt)
#         # print(']')
#         return self.lt
#     def __del__(self):
#         del self.lt

# s = St(input())
# print(s.Max())
# print(s.Min())
# print(s.ls())

# list=['j','k','l',8,9]
# print(list)
#class BMI:
#     name = None
#     age = None
#     height = None
#     weight = None
#     BMI = None
#     def __init__(self,name,age,height,weight):
#         self.name = name
#         self.age = age
#         self.height = height
#         self.weight = weight
#     def getBMI(self):
#         self.BMI=self.weight/(self.height*self.height)
#         return self.BMI
#     def getStatus(self):
#         if self.BMI < 18:
#             return "超轻"
#         elif self.BMI >= 18 and self.BMI < 25:
#             return "标准"
#         elif self.BMI >= 25 and self.BMI < 27:
#             return "超重"
#         elif self.BMI>=27:
#             return "肥胖"
#
#
# sName = input()  #输入姓名
# iAge = int(input()) #输入年龄
# fHeight = eval(input())  #输入身高，预期为浮点数，单位米
# fWeight = eval(input())  #输入体重，预期为浮点数，单位千克
# bmi=BMI(sName,iAge,fHeight,fWeight) #实例化BMI类
# print("Name:",bmi.name)
# print("Age:",bmi.age)
# print("BMI = %.3f" % bmi.getBMI())
# print("Result =",bmi.getStatus())
#
# class Point:
#     count1=0
#     def __init__(self, x, y):
#         self.x = x
#         self.y = y
#         Point.count1+=1
#     def getx(self):
#         return self.x
#     def gety(self):
#         return self.y
#
#     @classmethod
#     def count(a):
#         return a.count1
#
# points=[]
# try:
#     while True:
#       x,y=map(int,input().split(","))
#       points.append(Point(x,y))
# except EOFError:
#     pass
# n=Point.count()
# for i in range(n):
#     print("(",points[i].getx(),",",points[i].gety(),")",sep="")

# class Circle:
#     def __init__(self):
#         self.x=None
#         self.y=None
#         self.r=None
#     def SetCenter(self, x, y):
#         self.x=x
#         self.y=y
#     def SetRadius(self, r):
#         self.r=r
#     def PrintInfo(self):
#         print('x=%.2f'%self.x, 'y=%.2f'%self.y, 'r=%.2f'%self.r,sep=",")
#     def GetArea(self):
#         return self.r*self.r*3.14
#
#
#
#
# if __name__=='__main__':
#     c=Circle() #创建Circle类对象c
#     x=eval(input()) #输入圆心的x坐标
#     y=eval(input()) #输入圆心的y坐标
#     r=eval(input()) #输入半径
#     c.SetCenter(x,y) #设置圆心
#     c.SetRadius(r) #设置半径
#     c.PrintInfo() #输出圆的圆心和半径信息（均保留2位小数）
#     print('%.2f'%c.GetArea()) #输出圆的面积（保留2位小数）


# import requests
# from bs4 import BeautifulSoup
# import random
# import time
# import os
#
# # 配置代理池（可选）
# PROXIES = [
#     "http://proxy1_address:port",
#     "http://proxy2_address:port",
# ]
#
# # 请求头配置
# HEADERS = {
#     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
#     'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
#     'Accept-Language': 'en-US,en;q=0.5',
# }
#
# # 随机选择代理（如果需要）
# def get_random_proxy():
#     if PROXIES:
#         return {"http": random.choice(PROXIES), "https": random.choice(PROXIES)}
#     return None
#
# # 获取单页电影数据
# def parse_page(html):
#     soup = BeautifulSoup(html, 'html.parser')
#     movie_list = []
#
#     # 检查页面是否为空
#     if not soup.select('.board-wrapper dd'):
#         print("警告：未找到电影数据，可能是页面结构发生变化或反爬机制生效。")
#         return movie_list
#
#     for item in soup.select('.board-wrapper dd'):
#         try:
#             rank = item.select_one('.board-index').text.strip()
#             title = item.select_one('.name').text.strip()
#             actors = item.select_one('.star').text.strip()[3:].strip()  # 去掉 "主演：" 前缀
#             release_date = item.select_one('.releasetime').text.strip()[5:].strip()  # 去掉 "上映时间：" 前缀
#             rating = item.select_one('.score').text.strip()
#             movie_list.append((rank, title, actors, release_date, rating))
#         except AttributeError as e:
#             print(f"解析电影数据时出错: {e}")
#
#     return movie_list
#
# # 爬取猫眼电影榜单 Top100
# def scrape_maoyan():
#     base_url = 'https://maoyan.com/board/4?offset='
#     all_movies = []
#
#     try:
#         for offset in range(0, 100, 10):  # 每页 10 部电影，共 10 页
#             url = base_url + str(offset)
#             print(f'正在爬取: {url}')
#
#             # 设置随机延迟
#             time.sleep(random.uniform(1, 3))
#
#             # 使用随机代理（如果需要）
#             proxy = get_random_proxy()
#
#             # 发起请求
#             try:
#                 response = requests.get(url, headers=HEADERS, proxies=proxy)
#                 if response.status_code == 200:
#                     print(f"响应内容长度: {len(response.text)}")
#                     movies = parse_page(response.text)
#                     if not movies:
#                         print("未提取到数据，跳过该页。")
#                     else:
#                         all_movies.extend(movies)
#                         print(f'成功爬取 {len(movies)} 部电影数据')
#                 else:
#                     print(f'请求失败，状态码: {response.status_code}')
#             except Exception as e:
#                 print(f"请求失败: {e}")
#
#     except Exception as e:
#         print(f"发生错误: {e}")
#
#     # 保存数据到文件
#     save_to_file(all_movies)
#
# # 保存数据到文件
# def save_to_file(movies):
#     file_name = 'maoyan_top100.txt'
#     with open(file_name, 'w', encoding='utf-8') as f:
#         for movie in movies:
#             rank, title, actors, release_date, rating = movie
#             f.write(f"排名: {rank}\n")
#             f.write(f"名称: {title}\n")
#             f.write(f"主演: {actors}\n")
#             f.write(f"上映时间: {release_date}\n")
#             f.write(f"评分: {rating}\n")
#             f.write("-" * 50 + "\n")
#     print(f"数据已保存到文件: {os.path.abspath(file_name)}")
#
# if __name__ == '__main__':
#     scrape_maoyan()


import requests
import json
import folium


# Step 1: 爬取经纬度数据
def fetch_geo_data(url):
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        return data
    else:
        print("Failed to fetch data")
        return None


# Step 2: 提取经纬度数据并存储到文件
def extract_and_save_geo_data(data, file_path):
    provinces = []
    for feature in data['features']:
        province_name = feature['properties']['name']
        coordinates = feature['geometry']['coordinates']
        provinces.append({
            'name': province_name,
            'coordinates': coordinates
        })

    # Save to a JSON file
    with open(file_path, 'w', encoding='utf-8') as f:
        json.dump(provinces, f, ensure_ascii=False, indent=4)
    print(f"Data saved to {file_path}")
    return provinces


# Step 3: 使用 Folium 绘制地图
def visualize_geo_data(data):
    # 创建一个以中国为中心的地图
    china_map = folium.Map(location=[35, 105], zoom_start=4)

    # 添加各省市的边界
    for province in data:
        name = province['name']
        coordinates = province['coordinates']

        # 处理多边形坐标格式
        if isinstance(coordinates[0][0][0], list):  # MultiPolygon
            for polygon in coordinates:
                folium.Polygon(
                    locations=polygon[0],
                    color='blue',
                    fill=True,
                    fill_color='blue',
                    fill_opacity=0.2,
                    popup=name
                ).add_to(china_map)
        else:  # Polygon
            folium.Polygon(
                locations=coordinates[0],
                color='blue',
                fill=True,
                fill_color='blue',
                fill_opacity=0.2,
                popup=name
            ).add_to(china_map)

    # 保存为 HTML 文件
    china_map.save("china_map.html")
    print("Map visualization saved to china_map.html")


# 主函数
if __name__ == "__main__":
    # 配置参数
    url = "https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json"
    file_path = "provinces_geo_data.json"

    # Step 1: 爬取数据
    geo_data = fetch_geo_data(url)
    if geo_data:
        # Step 2: 提取并存储数据
        provinces_data = extract_and_save_geo_data(geo_data, file_path)

        # Step 3: 可视化数据
        visualize_geo_data(provinces_data)